#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<errno.h>

// 函数指针类型
typedef void (*funt_t)();

#define NUM 5
funt_t handlers[NUM+1];

void DownLoad()
{
    printf("这是一个下载的任务\n");
}
void Flush()
{
    printf("这是一个刷新的任务\n");
}
void Log()
{
    printf("这是一个记录日志的任务\n");
}

// 注册任务
void registerhandlers(funt_t h[], funt_t t)
{
    int i = 0;
    for(; i < NUM; i++)
    {
        if(h[i] == NULL) break;
    }
    if(i == NUM) return;
    h[i] = t;
    h[i+1] = NULL;
}

int main()
{
    registerhandlers(handlers, DownLoad);
    registerhandlers(handlers, Flush);
    registerhandlers(handlers, Log);

    pid_t id = fork();
    if(id == 0)
    {
        int cnt = 3;
        while(1)
        {
            printf("我是一个子进程，pid: %d, ppid: %d\n", getpid(), getppid());
            sleep(1);
            cnt--;
            // 设置错误
            //int a = 10;
            //a /= 0;
        }
        exit(10);
    }
    // 父进程
    while(1)
    {
        int status = 0;
        pid_t rid = waitpid(id, &status, WNOHANG);
        if(rid > 0)
        {
            printf("wait success, rid: %d, status: %d, exit signal: %d\n", rid, WEXITSTATUS(status), status&0xF);
            break;
        }
        else if(rid == 0)
        {
            // 非阻塞轮询
            for(int i = 0; handlers[i]; i++)
            {
                handlers[i]();
            }

            printf("本轮调用结束，子进程没有退出\n");
            sleep(1);
        }
        else
        {
            printf("等待失败\n");
            break;
        }
    }



    // 父进程
    // 1.子进程退出
    // 2.子进程没退出呢？
    //sleep(10);
    //pid_t rid = wait(NULL);
    //pid_t rid = waitpid(-1, NULL, 0);
    //pid_t rid = waitpid(id-1, NULL, 0);
    //int status = 0;
    //pid_t rid = waitpid(id, &status, 0);
    
    //if(WIFEXITED(status))
    //{
    //    printf("wait success, rid: %d, status: %d, exit signal: %d\n", rid, WEXITSTATUS(status), status&0xF); // 0xFF前24个为0，后8个为1
    //}
    //else
    //{
    //    printf("子进程退出异常！\n");
    //}
    //if(rid > 0)
    //{
    //    //printf("wait success, rid: %d, status: %d, exit signal: %d\n", rid, (status>>8)&0xFF, status&0xF); // 0xFF前24个为0，后8个为1
    //    printf("wait success, rid: %d, status: %d, exit signal: %d\n", rid, WEXITSTATUS(status), status&0xF); // 0xFF前24个为0，后8个为1
    //}
    //else
    //{
    //    printf("wait fail: %d: %s\n", errno, strerror(errno));
    //}
    //sleep(5);
    return 0;
}



